page.tsx 2.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475
  1. import { notFound, redirect } from "next/navigation";
  2. import { OrderDirection, ProductOrderField, SearchProductsDocument } from "@/gql/graphql";
  3. import { executeGraphQL } from "@/lib/graphql";
  4. import { Pagination } from "@/ui/components/Pagination";
  5. import { ProductList } from "@/ui/components/ProductList";
  6. import { ProductsPerPage } from "@/app/config";
  7. export const metadata = {
  8. title: "Search products · Saleor Storefront example",
  9. description: "Search products in Saleor Storefront example",
  10. };
  11. export default async function Page({
  12. searchParams,
  13. params,
  14. }: {
  15. searchParams: Record<"query" | "cursor", string | string[] | undefined>;
  16. params: { channel: string };
  17. }) {
  18. const cursor = typeof searchParams.cursor === "string" ? searchParams.cursor : null;
  19. const searchValue = searchParams.query;
  20. if (!searchValue) {
  21. notFound();
  22. }
  23. if (Array.isArray(searchValue)) {
  24. const firstValidSearchValue = searchValue.find((v) => v.length > 0);
  25. if (!firstValidSearchValue) {
  26. notFound();
  27. }
  28. redirect(`/search?${new URLSearchParams({ query: firstValidSearchValue }).toString()}`);
  29. }
  30. const { products } = await executeGraphQL(SearchProductsDocument, {
  31. variables: {
  32. first: ProductsPerPage,
  33. search: searchValue,
  34. after: cursor,
  35. sortBy: ProductOrderField.Rating,
  36. sortDirection: OrderDirection.Asc,
  37. channel: params.channel,
  38. },
  39. revalidate: 60,
  40. });
  41. if (!products) {
  42. notFound();
  43. }
  44. const newSearchParams = new URLSearchParams({
  45. query: searchValue,
  46. ...(products.pageInfo.endCursor && { cursor: products.pageInfo.endCursor }),
  47. });
  48. return (
  49. <section className="mx-auto max-w-7xl p-8 pb-16">
  50. {products.totalCount && products.totalCount > 0 ? (
  51. <div>
  52. <h1 className="pb-8 text-xl font-semibold">Search results for &quot;{searchValue}&quot;:</h1>
  53. <ProductList products={products.edges.map((e) => e.node)} />
  54. <Pagination
  55. pageInfo={{
  56. ...products.pageInfo,
  57. basePathname: `/search`,
  58. urlSearchParams: newSearchParams,
  59. }}
  60. />
  61. </div>
  62. ) : (
  63. <h1 className="mx-auto pb-8 text-center text-xl font-semibold">Nothing found :(</h1>
  64. )}
  65. </section>
  66. );
  67. }